package com.itlong.cloud.controller.visitor;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.app.AppGetVisitPassWordDTO;
import com.itlong.cloud.POJO.DTO.app.CreateDeviceMarkDTO;
import com.itlong.cloud.POJO.DTO.app.MiniSetVisitPassFaceDTO;
import com.itlong.cloud.POJO.DTO.common.PadFaceSyncDataDTO;
import com.itlong.cloud.POJO.DTO.common.WeChatVisitorMsgDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyAddVisitorDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyGetVisitorInfoDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyVisitorPassRecordGetDTO;
import com.itlong.cloud.POJO.PO.AppVisitorPassCodeRecordPO;
import com.itlong.cloud.POJO.PO.ProjectPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.*;
import com.itlong.cloud.POJO.VO.operate.OperateFaceApplyInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperateProjectDetailVO;
import com.itlong.cloud.POJO.VO.property.PropertyGetVisitorInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyVisitorInfoVO;
import com.itlong.cloud.POJO.VO.property.PropertyVisitorPassRecordGetVO;
import com.itlong.cloud.POJO.VO.property.PropertyVisitorSendMessageVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.VisitorOperateTypeEnum;
import com.itlong.cloud.enumerate.ecode.*;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.equip.app.IAppVisitorPassCodeRecordServiceClient;
import com.itlong.cloud.equip.property.IPadFaceSyncDataServiceClient;
import com.itlong.cloud.iottp.IIotBaiduFaceServiceClient;
import com.itlong.cloud.iottp.IIotTpSmsServiceClient;
import com.itlong.cloud.iottp.IWeChatTemplateMsgServiceClient;
import com.itlong.cloud.project.operate.IOperateFaceApplyServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.property.IPropertyVisitorPassRecordServiceClient;
import com.itlong.cloud.user.property.IPropertyVisitorServiceClient;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.page.PageByVisitor;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *      物业访客管理Controller
 * </desc>
 *
 * @createDate 2018/06/27
 */
@RestController
@RequestMapping("/visitor")
@RefreshScope
public class PropertyVisitorController {

    private static final Logger LOG = LoggerFactory.getLogger(PropertyVisitorController.class);

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;
    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;
    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;
    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;
    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Autowired
    IPropertyVisitorPassRecordServiceClient iPropertyVisitorPassRecordServiceClient;
    @Autowired
    IPropertyVisitorServiceClient iPropertyVisitorServiceClient;
    @Autowired
    IIotTpSmsServiceClient iIotTpSmsServiceClient;
    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;
    @Autowired
    IPadFaceSyncDataServiceClient iPadFaceSyncDataServiceClient;
    @Autowired
    IWeChatTemplateMsgServiceClient iWeChatTemplateMsgServiceClient;

    @Autowired
    IOperateFaceApplyServiceClient iOperateFaceApplyServiceClient;

    @Autowired
    IIotBaiduFaceServiceClient iIotBaiduFaceServiceClient;

    @Autowired
    IAppVisitorPassCodeRecordServiceClient iAppVisitorPassCodeRecordServiceClient;


    @Autowired
    IAppDeviceServiceClient iAppDeviceServiceClient;

    /**
     * <desc>
     *     访客通行记录列表
     * <desc/>
     *
     *@param  visitorPassRecordGetDTO  分页查询访客通行记录
     * @return  MessageVO 标准格式化响应结果
     * @author JuGuang.S
     * @createDate 2018/06/27
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "/passRecord/getByPage")
    public Object getVisitorPassRecordByPage(PropertyVisitorPassRecordGetDTO visitorPassRecordGetDTO) throws Exception {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            visitorPassRecordGetDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyVisitorPassRecordGetDTO.class, request);
            if (visitorPassRecordGetDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            Page<PropertyVisitorPassRecordGetVO> result = iPropertyVisitorPassRecordServiceClient.getVisitorPassRecordByPage(visitorPassRecordGetDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【物业_访客通行记录】分页查询失败", e);
        }
    }


    /**
     * <desc>
     *      保存访客
     * </desc>
     * @param propertyAddVisitorDTO
     * @return
     * @throws Exception
     * @author Jiaqi.X
     * @createDate 2018/06/28
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "addVisitor")
    @LoggerInfo(operateDesc = LogDescConstant.SAVE_VISITOR_INFO_DESC)
    public Object addVisitor(PropertyAddVisitorDTO propertyAddVisitorDTO) throws Exception {
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyAddVisitorDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAddVisitorDTO.class, request);
            if (propertyAddVisitorDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //查询当前所选房间下的业主userId
            List<AppFloorDevicesVO> lists =  new ArrayList<>();
            List<AppFloorDevicesVO> listAll =  new ArrayList<>();
            if(StringUtils.isNotEmpty(propertyAddVisitorDTO.getDeviceUniques())){
                String userId = iAppDeviceServiceClient.getOwnerUserIdByroomId(propertyAddVisitorDTO.getRoomId(),propertyAddVisitorDTO.getProjectId());
                propertyAddVisitorDTO.setOwnerUserId(userId);
                lists = iAppDeviceServiceClient.getUserTemporaryAuthFloorDevices(userId,propertyAddVisitorDTO.getProjectId());
                listAll = iAppDeviceServiceClient.getFloorDevices(userId,propertyAddVisitorDTO.getProjectId(),0);
                propertyAddVisitorDTO.setLists(lists);
                propertyAddVisitorDTO.setListAll(listAll);
            }
            AppVisitorPassCodeRecordPO po = iPropertyVisitorServiceClient.addVisitor(propertyAddVisitorDTO);
            PropertyVisitorSendMessageVO sendMessageVO = iPropertyVisitorServiceClient.getVisitorMessage(po.getPassId());
            String content = "您的访客通行密码:"+sendMessageVO.getPassword()+"，用于"+sendMessageVO.getAddress()+"。有效时间为"+sendMessageVO.getStartTime()+"至"+sendMessageVO.getEndTime()+"前。点击链接"+sendMessageVO.getQrcodeUrl()+" ，查看访客二维码，您也可通过扫描该二维码进行通行";
            if(StringUtils.isNotEmpty(sendMessageVO.getVisitorPhone())){
                iIotTpSmsServiceClient.sendSmsCodeByPhone(sendMessageVO.getVisitorPhone(),content);
            }
            Map<String,Object> result = new HashMap<>();
            result.put("passId",po.getPassId());

            if (propertyAddVisitorDTO.getImageStr() != null && !"".equals(propertyAddVisitorDTO.getImageStr())) {
                MiniSetVisitPassFaceDTO miniSetVisitPassFaceDTO = new MiniSetVisitPassFaceDTO();
                miniSetVisitPassFaceDTO.setImageStr(propertyAddVisitorDTO.getImageStr());
                miniSetVisitPassFaceDTO.setPassId(po.getPassId());
                miniSetVisitPassFaceDTO.setProjectId(propertyAddVisitorDTO.getProjectId());
                miniSetVisitPassFaceDTO.setIdcardKey(propertyAddVisitorDTO.getIdcardKey());
                messageVO = this.setVisitPassFacePrivate(miniSetVisitPassFaceDTO);
                if (messageVO.getMsgCode() != 0) {
                    iAppVisitorPassCodeRecordServiceClient.deleteVisitorInfo(po.getPassId());
                    return messageVO;
                }
            }

            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【物业_访客管理_保存访客】保存访客失败", e);
        }
    }



    /**
     * <desc>
     *      保存访客人脸(私有)
     * </desc>
     *
     * @param dto 接收数据dto类
     * @return
     * @author Qiang.S
     * @createDate 2019/02/26
     */
    private MessageVO setVisitPassFacePrivate(MiniSetVisitPassFaceDTO dto) throws Exception{
        if (StringUtils.isBlank(dto.getImageStr())){
            return new MessageVO(AppErrorCodeEnum.IMAGE_DATA_INVALID.getErrorCode());
        }
        Map<String, String> map = new HashMap<>();
        //判断项目是否开启人脸识别,并查询是否有百度库key
        OperateFaceApplyInfoVO operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(dto.getProjectId());
        if(operateFaceApplyInfoVO == null){
            ErrorCode errorCode = AppErrorCodeEnum.PROJECT_FACE_APPID_INEXISTENCE.getErrorCode();
            return new MessageVO(errorCode);
        }
        //判断图片是否合格
        String[] imageStrS = dto.getImageStr().split(",");
        dto.setImageStr(imageStrS[1]);
        //访客人脸注册时,判断人脸库中是否有此人数据
        AppCreateBaiduFaceVO appCreateBaiduFaceVO = new AppCreateBaiduFaceVO();
        appCreateBaiduFaceVO.setAPP_ID(operateFaceApplyInfoVO.getAppId());
        appCreateBaiduFaceVO.setAPI_KEY(operateFaceApplyInfoVO.getApiKey());
        appCreateBaiduFaceVO.setSECRET_KEY(operateFaceApplyInfoVO.getSecretKey());
        appCreateBaiduFaceVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore()==0F?80F:operateFaceApplyInfoVO.getFaceScore());
//        appCreateBaiduFaceVO.setFile(new BASE64Decoder().decodeBuffer(dto.getImageStr()));
        String uploadFilePath = uploadImageFile(new BASE64Decoder().decodeBuffer(dto.getImageStr()), "jpg", FileCatalogEnum.BAIDU_FACE_CREATE_FILE);
        appCreateBaiduFaceVO.setImageUrl(uploadFilePath);
        if (StringUtils.isBlank(uploadFilePath)) {
            return new MessageVO(AppErrorCodeEnum.IMAGE_UPLOAD_FAILED.getErrorCode());
        }
        String checkResult = iIotBaiduFaceServiceClient.faceVerify(appCreateBaiduFaceVO);
        if (checkResult != null && !"".equals(checkResult)) {
            if ("error".equals(checkResult)) {//调用接口异常
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACEVERFY_ERROR.getErrorCode());
            }
            if ("busy".equals(checkResult)) {//调用接口忙
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode());
            }
            if ("others".equals(checkResult)) {//图片不合格,非真人图片
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_PICTURE_ERROR.getErrorCode());
            }
            if ("result_num".equals(checkResult)) {//人脸数异常
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_RESULTNUM_NOT_1.getErrorCode());
            }
            if ("size".equals(checkResult)) {//人脸太小
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_SIZE_TOO_SMALL.getErrorCode());
            }
            //2020年8月5号 按照需求说明取消活体检测
         /*   if ("faceliveness".equals(checkResult)) {//活体值异常
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_FACELIVENESS_TOO_LOW.getErrorCode());
            }*/
            if ("left_eye".equals(checkResult) || "right_eye".equals(checkResult) || "nose".equals(checkResult)
                    || "mouth".equals(checkResult) || "left_cheek".equals(checkResult) || "right_cheek".equals(checkResult)
                    || "chin".equals(checkResult)) {//图片遮挡
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_OCCLUSION.getErrorCode());
            }
            if ("blur".equals(checkResult)) {//模糊
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_BLUR_TOO_LOW.getErrorCode());
            }
            if ("illumination_min".equals(checkResult)) {//光照过暗
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_LOW.getErrorCode());
            }
            if ("illumination_max".equals(checkResult)) {//光照过亮
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ILLUMINATION_TOO_HIGH.getErrorCode());
            }
            if ("pitch".equals(checkResult) || "roll".equals(checkResult) || "yaw".equals(checkResult)) {//角度
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_ANGLE_NOT_STRAIGHT.getErrorCode());
            }
            if ("completeness".equals(checkResult)) {//人脸完整度
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_FACE_COMPLETENESS_IMPERFECT.getErrorCode());
            }
        }
        String repeatResult = iIotBaiduFaceServiceClient.identifyUser(appCreateBaiduFaceVO);//拿到现有的id
        if (repeatResult != null && !"".equals(repeatResult)) {
            if ("error".equals(repeatResult)) {//调用接口异常
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_IDENTIFY_ERROR.getErrorCode());
            }
            if ("busy".equals(repeatResult)) {//调用接口忙
                return new MessageVO(PropertyErrorCodeEnum.APPUSER_BAIDU_BUSY.getErrorCode());
            }
        }
        String vFaceId;
        //判断认证图片是否重复
        if (repeatResult == null) {//人脸库中无此人脸ID使用V_ + pass_id
            appCreateBaiduFaceVO.setUid("V_"+dto.getPassId());
            //创建百度人脸信息
            boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
            if (!result) {
                map.put("result","2");
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
            }
            vFaceId = appCreateBaiduFaceVO.getUid();
        }else {//人脸库中有此人脸
            //有此人脸时证明这个人在此项目中注册过人脸业主使用的是这个人的user_id,访客使用的是V_ + pass_id   不进行重复注册
            if (repeatResult.substring(0,2).equals("V_")) {//访客人脸则进行覆盖
                appCreateBaiduFaceVO.setUid(repeatResult);
                //创建百度人脸信息
                boolean result = iIotBaiduFaceServiceClient.doCreateBaiduFaceForVisitor(appCreateBaiduFaceVO);
                if (!result) {
                    map.put("result","2");
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
                }
            }
            vFaceId = repeatResult;
        }
        iAppVisitorPassCodeRecordServiceClient.setVisitPassFace(dto.getPassId(), uploadFilePath, vFaceId, dto.getProjectId(), dto.getIdcardKey()==null?"":dto.getIdcardKey(),0);

        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        map.put("authDate",formatter.format(currentTime));
        map.put("result","1");
        map.put("uploadFilePath",uploadFilePath);
        //查询当前项目信息
        ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(dto.getProjectId());
        // 平板优先离线，则插入同步数据
        if (projectPO.getOnOffLinePadFace() != null) {
            PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
            padFaceSyncDataDTO.setOperateType("3");
            padFaceSyncDataDTO.setProjectId(dto.getProjectId());
            padFaceSyncDataDTO.setPassId(dto.getPassId());
            padFaceSyncDataDTO.setStatus("1");
            padFaceSyncDataDTO.setSourceSystem(2);
            if(projectPO.getOnOffLinePadFace() == 1){
                iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
            }
            iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
        }
        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),map);
    }

    /**
     * <desc>
     *     根据房屋编号模糊查询房间
     * <desc/>
     *
     *@param  unitId  单元编号
     *@param  roomNum  房间编号
     * @return  MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/05/14
     */
    @ResponseBody
    @PostMapping(path = "/visitorInfo/getRoomInfoByNum")
    public Object getRoomInfoByNum(String unitId, String roomNum) throws Exception {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            unitId = request.getAttribute("unitId") == null ? null : request.getAttribute("unitId").toString();
            roomNum = request.getAttribute("roomNum") == null ? null : request.getAttribute("roomNum").toString();
            if (unitId == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), iPropertyVisitorServiceClient.getRoomInfoByNum(unitId, roomNum));
        } catch (Exception e) {
            throw new DataAccessException("【物业_添加访客】根据房屋编号模糊查询房间失败", e);
        }
    }

    /**
     * <desc>
     *     获取物业访客配置
     * <desc/>
     *
     * @param  projectId  房间编号
     * @return  MessageVO 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2020/05/22
     */
    @ResponseBody
    @PostMapping(path = "/visitorInfo/getVisitorConfigure")
    public Object getVisitorConfigure(String projectId) throws Exception {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if (projectId == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), iPropertyVisitorServiceClient.getVisitorConfigure(projectId));
        } catch (Exception e) {
            throw new DataAccessException("【物业_添加访客】根据房屋编号模糊查询房间失败", e);
        }
    }

    /**
     * <desc>
     *     访客列表
     * <desc/>
     *
     *@param  visitorInfoDTO  分页查询访客列表
     * @return  MessageVO 标准格式化响应结果
     * @author JuGuang.S
     * @createDate 2018/06/28
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "/visitorInfo/getByPage")
    public Object getVisitorInfoByPage(PropertyGetVisitorInfoDTO visitorInfoDTO) throws Exception {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            visitorInfoDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyGetVisitorInfoDTO.class, request);
            if (visitorInfoDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            PageByVisitor<PropertyVisitorInfoVO> result = iPropertyVisitorServiceClient.getVisitorInfoByPage(visitorInfoDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【物业_访客列表】分页查询失败", e);
        }
    }

    /**
     * <desc>
     *     重新访问访客信息的回显、查看和打印二维码共用此接口
     * <desc/>
     *
     *@param  passId  访客ID
     * @return  MessageVO 标准格式化响应结果
     * @author JuGuang.S
     * @createDate 2018/06/29
     */
    @ResponseBody
    @PostMapping(path = "/getVisitorInfo")
    public Object getVisitorInfo(String passId) throws Exception {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            passId = request.getAttribute("passId") == null ? null : request.getAttribute("passId").toString();
            if (StringUtils.isEmpty(passId)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            PropertyGetVisitorInfoVO infoVO = iPropertyVisitorServiceClient.getVisitorInfo(passId);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), infoVO);
        } catch (Exception e) {
            throw new DataAccessException("【物业_根据访客ID获取访客信息】查询失败", e);
        }
    }

    /**
     * <desc>
     *     根据访客ID删除访客信息
     * <desc/>
     *
     *@param  passId  访客ID多个以逗号分隔
     * @return  MessageVO 标准格式化响应结果
     * @author JuGuang.S
     * @createDate 2018/06/29
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "/delete")
    @LoggerInfo(operateDesc = LogDescConstant.DELETE_VISITOR_INFO_DESC)
    public Object deleteVisitorInfo(String passId,String projectId) throws Exception {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            passId = request.getAttribute("passId") == null ? null : request.getAttribute("passId").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if (StringUtils.isEmpty(passId)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            String[] visitorArr = StringHandlerUtil.splitString(passId);
            iPropertyVisitorServiceClient.deleteVisitorInfo(projectId,visitorArr);
            //查询当前项目信息
            ProjectPO projectPO = iOperateProjectServiceClient.getOneProject(projectId);
            // 平板优先离线，则插入同步数据
            if (projectPO.getOnOffLinePadFace() != null) {
                PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                padFaceSyncDataDTO.setOperateType("3");
                padFaceSyncDataDTO.setProjectId(projectId);
                padFaceSyncDataDTO.setPassId(passId);
                padFaceSyncDataDTO.setStatus("0");
                padFaceSyncDataDTO.setSourceSystem(2);
                if(projectPO.getOnOffLinePadFace() == 1){
                    iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
                }
                padFaceSyncDataDTO.setStatus("2");
                iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
            }
            return new MessageVO(passId,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业_根据访客删除访客信息】失败", e);
        }
    }

    /**
     * <desc>
     *     根据访客ID重发短信
     * <desc/>
     *
     *@param  passId  访客ID多个以逗号分隔
     * @return  MessageVO 标准格式化响应结果
     * @author JuGuang.S
     * @createDate 2018/06/29
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "/sendMessage")
    public Object visitorSendMessage(String passId) throws Exception {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            passId = request.getAttribute("passId") == null ? null : request.getAttribute("passId").toString();
            if (StringUtils.isEmpty(passId)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            PropertyVisitorSendMessageVO sendMessageVO = iPropertyVisitorServiceClient.getVisitorMessage(passId);
            if(sendMessageVO == null){
                return new MessageVO(PropertyErrorCodeEnum.VISITOR_INFO_NOT_EXIST_ERR.getErrorCode());
            }
            if(sendMessageVO.getSendMessageCount()>=3){
                return new MessageVO(PropertyErrorCodeEnum.VISITOR_SEND_MESSAGE_ERR.getErrorCode());
            }
            String content = "您的访客通行密码:"+sendMessageVO.getPassword()+"，用于"+sendMessageVO.getAddress()+"。有效时间为"+sendMessageVO.getStartTime()+"至"+sendMessageVO.getEndTime()+"前。点击链接"+sendMessageVO.getQrcodeUrl()+" ，查看访客二维码，您也可通过扫描该二维码进行通行";
            Boolean sendFlag = iIotTpSmsServiceClient.sendSmsCodeByPhone(sendMessageVO.getVisitorPhone(),content);
            if(sendFlag){
                //根据PassId更新已发送短信的次数
                iPropertyVisitorServiceClient.updateSendMssCount(passId);
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
            }
            return new MessageVO(PropertyErrorCodeEnum.VISITOR_SEND_MESSAGE_FAILED.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业_根据访客ID重发短信】失败", e);
        }
    }

    /**
     * <desc>
     *      重新访问修改访客信息
     * </desc>
     * @param propertyAddVisitorDTO
     * @return
     * @throws Exception
     * @author JuGuang.S
     * @createDate 2018/07/02
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "renewVisitor")
    @LoggerInfo(operateDesc = LogDescConstant.MODIFY_VISITOR_INFO_DESC)
    public Object renewVisitor(PropertyAddVisitorDTO propertyAddVisitorDTO) throws Exception {
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyAddVisitorDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyAddVisitorDTO.class, request);
            if (propertyAddVisitorDTO == null) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppVisitorPassCodeRecordPO oldPO = iPropertyVisitorServiceClient.getVisitorByRenewVisitor(propertyAddVisitorDTO.getPassId());
            //查询当前所选房间下的业主userId
            List<AppFloorDevicesVO> lists =  new ArrayList<>();
            List<AppFloorDevicesVO> listAll =  new ArrayList<>();
            if(StringUtils.isNotEmpty(propertyAddVisitorDTO.getDeviceUniques())){
                String userId = iAppDeviceServiceClient.getOwnerUserIdByroomId(propertyAddVisitorDTO.getRoomId(),propertyAddVisitorDTO.getProjectId());
                propertyAddVisitorDTO.setOwnerUserId(userId);
                lists = iAppDeviceServiceClient.getUserTemporaryAuthFloorDevices(userId,propertyAddVisitorDTO.getProjectId());
                listAll = iAppDeviceServiceClient.getFloorDevices(userId,propertyAddVisitorDTO.getProjectId(),0);
                propertyAddVisitorDTO.setLists(lists);
                propertyAddVisitorDTO.setListAll(listAll);
            }
            AppVisitorPassCodeRecordPO po = iPropertyVisitorServiceClient.addVisitor(propertyAddVisitorDTO);
            PropertyVisitorSendMessageVO sendMessageVO = iPropertyVisitorServiceClient.getVisitorMessage(po.getPassId());
            String content = "您的访客通行密码:"+sendMessageVO.getPassword()+"，用于"+sendMessageVO.getAddress()+"。有效时间为"+sendMessageVO.getStartTime()+"至"+sendMessageVO.getEndTime()+"前。点击链接"+sendMessageVO.getQrcodeUrl()+" ，查看访客二维码，您也可通过扫描该二维码进行通行";
            Boolean sendFlag = iIotTpSmsServiceClient.sendSmsCodeByPhone(sendMessageVO.getVisitorPhone(),content);
            Map<String,Object> result = new HashMap<>();
//            result.put("password",po.getPassword());
//            result.put("startTime", DateUtil.fomatDate(po.getStartTime(),DateUtil.DATE_FORMAT_TYPE1));
//            result.put("endTime",DateUtil.fomatDate(po.getEndTime(),DateUtil.DATE_FORMAT_TYPE1));
//            result.put("qrcodeUrl",po.getQrcodeUrl());
            result.put("passId",po.getPassId());
            //激活创建人脸后更新数据
            if (propertyAddVisitorDTO.getImageStr() != null && !"".equals(propertyAddVisitorDTO.getImageStr())) {
                MiniSetVisitPassFaceDTO miniSetVisitPassFaceDTO = new MiniSetVisitPassFaceDTO();
                miniSetVisitPassFaceDTO.setImageStr(propertyAddVisitorDTO.getImageStr());
                miniSetVisitPassFaceDTO.setPassId(po.getPassId());
                miniSetVisitPassFaceDTO.setProjectId(propertyAddVisitorDTO.getProjectId());
                miniSetVisitPassFaceDTO.setIdcardKey(propertyAddVisitorDTO.getIdcardKey());
                messageVO = this.setVisitPassFacePrivate(miniSetVisitPassFaceDTO);
                if (messageVO.getMsgCode() != 0) {
                    //由于此操作是重新访问，若注册人脸不成功无须删除,并且需将先前的数据恢复至数据库中
                    iPropertyVisitorServiceClient.update(oldPO);
                    //iAppVisitorPassCodeRecordServiceClient.deleteVisitorInfo(po.getPassId());
                    return messageVO;
                }
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException("【物业_访客管理_修改访客】修改访客失败", e);
        }
    }

    /**
     * <desc>
     *      访客单审批
     * </desc>
     * @param passId 访客单ID
     * @param checkStatus 物业审核状态 1代表审批通过 2代表审批拒绝
     * @return
     * @author JuGuang.S
     * @createDate 2019/04/25
     */
    @ResponseBody
    @AuthAccessRequired
    @PostMapping(path = "checkVisitor")
    @LoggerInfo(operateDesc = LogDescConstant.CHECK_VISITOR_DESC)
    public Object propertyCheckVisitor(String passId,Integer checkStatus,String loginUserId,String projectId,String visitorTime){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            passId = request.getAttribute("passId") == null ? null : request.getAttribute("passId").toString();
            loginUserId = request.getAttribute("loginUserId") == null ? null : request.getAttribute("loginUserId").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            checkStatus = request.getAttribute("checkStatus") == null ? null : (Integer) request.getAttribute("checkStatus");
            visitorTime = request.getAttribute("visitorTime") == null ? null : request.getAttribute("visitorTime").toString();
            OperateProjectDetailVO operateProjectDetailVO = iOperateProjectServiceClient.getDetail(projectId);
            if(operateProjectDetailVO.getMiniVisitorProperty()==1 && operateProjectDetailVO.getMiniVisitorOwner()==1){
                //如该项目配置物业和业主都需审批，则判断该通行业主是否已审批，否则不允许物业审批
                PropertyGetVisitorInfoVO infoVO = iPropertyVisitorServiceClient.getVisitorInfo(passId);
                if(infoVO.getOwnerCheckStatus()==0){
                    return new MessageVO(PropertyErrorCodeEnum.PROPERTY_VISITOR_CHECK.getErrorCode());
                }
            }
            if(iPropertyVisitorServiceClient.propertyCheckVisitor(passId,checkStatus,loginUserId,2)>0){
                WeChatVisitorMsgDTO msgDTO = new WeChatVisitorMsgDTO();
                if(checkStatus==1){
                    //审批时拜访时间发生变化后，需重新处理二维码相关逻辑
                    AppVisitorPassCodeRecordPO recordPO = iPropertyVisitorServiceClient.getVisitorByRenewVisitor(passId);
                    //校验审批时拜访时间是否有变化，若有则变更二维码相关逻辑
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String startStr = String.format("%s%s",visitorTime," 00:00:00");
                    if(!dateFormat.format(recordPO.getStartTime()).equals(startStr)){
                        AppGetVisitPassWordDTO appGetVisitPassWordDTO = new AppGetVisitPassWordDTO();
                        appGetVisitPassWordDTO.setPassId(passId);
                        appGetVisitPassWordDTO.setVisitTime(visitorTime);
                        appGetVisitPassWordDTO.setDeviceUniques(recordPO.getTemporaryAuthDeviceUniques());
                        appGetVisitPassWordDTO.setRoomId(recordPO.getRoomId());
                        appGetVisitPassWordDTO.setProjectId(projectId);
                        appGetVisitPassWordDTO.setIntervieweePhone(recordPO.getIntervieweePhone());
                        iAppVisitorPassCodeRecordServiceClient.updateQrcodeByTimeModify(appGetVisitPassWordDTO);
                    }
                    msgDTO.setOperateType(VisitorOperateTypeEnum.PROPERTY_CHECK_PASS.getType().toString());

                    // 平板优先离线且只需要业主审核无需物业审核则插入同步数据
                    if (operateProjectDetailVO.getOnOffLinePadFace() != null) {
                        PadFaceSyncDataDTO padFaceSyncDataDTO = new PadFaceSyncDataDTO();
                        padFaceSyncDataDTO.setOperateType("3");
                        padFaceSyncDataDTO.setProjectId(projectId);
                        padFaceSyncDataDTO.setPassId(passId);
                        padFaceSyncDataDTO.setStatus("1");
                        padFaceSyncDataDTO.setSourceSystem(2);
                        if(operateProjectDetailVO.getOnOffLinePadFace() == 1){
                            iPadFaceSyncDataServiceClient.userOrFloorSync(padFaceSyncDataDTO);
                        }
                        iPadFaceSyncDataServiceClient.userOrFloorSyncSmartCard(padFaceSyncDataDTO);
                    }
                }else{
                    msgDTO.setOperateType(VisitorOperateTypeEnum.CHECK_REFUSE.getType().toString());
                }
                msgDTO.setPassId(passId);
                iWeChatTemplateMsgServiceClient.sendWeChatTemplateMsg(msgDTO);
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【物业_访客管理_访客单审核】访客单审核失败", e);
        }
    }

    /**
     * <desc>
     *      获取当前用户临时权限设备列表
     * </desc>
     *
     * @param roomId
     * @param projectId 项目编号
     * @return
     * @author Juguang.S
     * @createDate 2019/09/03
     */
    @RequestMapping(value = "/getVisitorDeviceList",method = RequestMethod.POST)
    @ResponseBody
    public Object getUserTemporaryAuthDeviceList(String roomId,String projectId){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            roomId = request.getAttribute("roomId") == null ? null : request.getAttribute("roomId").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();

            if(StringUtils.isEmpty(projectId) || StringUtils.isEmpty(roomId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            String userId = iAppDeviceServiceClient.getOwnerUserIdByroomId(roomId,projectId);
            if(StringUtils.isEmpty(userId)){
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),new ArrayList<>());
            }

            //获取当前用户临时权限
            List<AppUserDevicesVO> deviceList = iAppDeviceServiceClient.getUserDevicesInfo(userId, projectId);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),deviceList);
        }catch ( Exception e){
            throw new DataAccessException("【物业_访客管理】添加访客获取用户临时权限设备列表失败",e);
        }

    }

    /**
     * <desc>
     *      创建访客时创建或修改标签
     * </desc>
     *
     * @param deviceMarkDTO 创建或修改标签的信息
     * @return
     * @author Juguang.S
     * @createDate 2019/09/03
     */
    @ResponseBody
    @LoggerInfo(operateDesc = LogDescConstant.CREATE_OR_UPDATE_DEVEICE_MARKS_INFO)
    @RequestMapping(value = "/createDeviceMark",method = RequestMethod.POST)
    public Object createDeviceMark(CreateDeviceMarkDTO deviceMarkDTO){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceMarkDTO = HttpProtocolUtil.parseRequestParamToDTO(CreateDeviceMarkDTO.class, request);
            deviceMarkDTO.setLoginUserId(deviceMarkDTO.getLoginUserId());
            iAppDeviceServiceClient.saveOrUpdateDeviceMark(deviceMarkDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch ( Exception e){
            throw new DataAccessException("【物业_访客管理】创建访客时创建或修改标签失败",e);
        }
    }

    /**
     * <desc>
     *      获取当前用户的设备标签
     * </desc>
     *
     * @param loginUserId 当前登录物业账号ID
     * @param projectId 项目编号
     * @return
     * @author Juguang.S
     * @createDate 2019/09/03
     */
    @ResponseBody
    @RequestMapping(value = "/getDeviceMark",method = RequestMethod.POST)
    public Object getDeviceMark(String projectId,String loginUserId){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            loginUserId = request.getAttribute("loginUserId") == null ? null : request.getAttribute("loginUserId").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if(StringUtils.isEmpty(projectId) || StringUtils.isEmpty(loginUserId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<VisitorDeviceMarkInfoVO> markList= iAppDeviceServiceClient.getDeviceMark(loginUserId,projectId);
            JSONObject js = new JSONObject();
            js.put("markAry",markList);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),js);
        }catch ( Exception e){
            throw new DataAccessException("【物业_访客管理】获取当前用户的设备标签失败",e);
        }
    }

    /**
     * <desc>
     *      删除设备标签
     * </desc>
     *
     * @param projectId 项目编号
     * @param markId 标签ID
     * @return
     * @author Juguang.S
     * @createDate 2019/09/03
     */
    @ResponseBody
    @RequestMapping(value = "/deleteDeviceMark",method = RequestMethod.POST)
    @LoggerInfo(operateDesc = LogDescConstant.DELETE_DEVEICE_MARKS_INFO)
    public Object deleteDeviceMark(String projectId,String markId){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            markId = request.getAttribute("markId") == null ? null : request.getAttribute("markId").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if(StringUtils.isEmpty(projectId) || StringUtils.isEmpty(markId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iAppDeviceServiceClient.deleteDeviceMark(markId);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch ( Exception e){
            throw new DataAccessException("【物业_访客管理】删除设备标签失败",e);
        }
    }

    /**
     * <desc>
     *      上传图片文件
     * <desc/>
     *
     * @param bytes 图片二进制
     * @param imageType 图片类型
     * @return
     * @author Qiang.S
     * @createDate 2018-05-07
     */
    private String uploadImageFile(byte[] bytes,String imageType, FileCatalogEnum fileCatalog){
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                byteArrayInputStream,
                imageType,
                FILE_ACCESS_URL,
                fileCatalog.getType()
        );
        try {
            //LOG.info("正在上传图片");
            Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
            //LOG.info("图片上传完毕");
            String returnCode = resultMap.get("returnCode").toString();
            if ("true".equals(returnCode)){
                String fileUrl = resultMap.get("accessPath").toString();
                return fileUrl;
            }else {
                LOG.info(String.format("图片上传失败，returnCode: %s",returnCode));
                return null;
            }
        } catch (IOException e) {
            LOG.info("UploadFileUtil.uploadFile失败", e);
            return null;
        }
    }

    /**
     * <desc>
     *      获取访客时间限制信息
     * </desc>
     *
     * @param projectId 项目编号
     * @return
     * @author Juguang.S
     * @createDate 2019/09/15
     */
    @ResponseBody
    @RequestMapping(value = "/getVisitorTimeInfo",method = RequestMethod.POST)
    public Object getVisitorTimeInfo(String projectId){
        try{
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if(StringUtils.isEmpty(projectId)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),iPropertyVisitorServiceClient.getVisitorTimeInfo(projectId));
        }catch ( Exception e){
            throw new DataAccessException("【物业_访客管理】获取访客时间限制信息失败",e);
        }
    }
}